<template>
  <div class="beidou-grid-map">
    <div id="cesiumContainer"></div>
    <div class="controls">
      <div class="control-item">
        <label>网格级别：</label>
        <select v-model="currentLevel">
          <option v-for="option in levelOptions" :key="option.value" :value="option.value">{{ option.label }}</option>
        </select>
      </div>
      <div class="control-item">
        <label>显示编码：</label>
        <input type="checkbox" v-model="showGridCode" />
      </div>
      <div class="control-item">
        <label>显示主要城市：</label>
        <input type="checkbox" v-model="showCities" />
      </div>
    </div>
  </div>
</template>

<script>
import * as Cesium from "cesium";
import { onMounted, ref, watch } from "vue";
import { BeidouGridCode } from "../utils/BeidouGridCode";
import "../Widgets/widgets.css";

Cesium.Ion.defaultAccessToken =
  "";

export default {
  name: "BeidouGridMap",
  setup() {
    const viewer = ref(null);
    const currentLevel = ref(1);
    const showGridCode = ref(true);
    const showCities = ref(true);
    const gridEntities = ref(new Map());

    // 中国主要城市数据
    const MAJOR_CITIES = [
      { name: "北京", lon: 116.4074, lat: 39.9042 },
      { name: "上海", lon: 121.4737, lat: 31.2304 },
      { name: "广州", lon: 113.2644, lat: 23.1291 },
      { name: "成都", lon: 104.0668, lat: 30.5728 },
      { name: "西安", lon: 108.9402, lat: 34.3416 },
      { name: "乌鲁木齐", lon: 87.6168, lat: 43.8256 },
      { name: "拉萨", lon: 91.1119, lat: 29.9625 },
      { name: "哈尔滨", lon: 126.6424, lat: 45.7575 }
    ];

    // 高度层级配置
    const HEIGHT_LEVELS = {
      LEVEL_1: [0, 10000, 20000, 30000, 40000, 50000], // 单位：米
      LEVEL_2: [0, 5000, 10000, 15000, 20000],
      LEVEL_3: [0, 2000, 4000, 6000, 8000, 10000],
      LEVEL_4: [0, 1000, 2000, 3000, 4000],
      LEVEL_5: [0, 500, 1000, 1500, 2000],
      LEVEL_6: [0, 250, 500, 750, 1000],
      LEVEL_7: [0, 100, 200, 300, 400],
      LEVEL_8: [0, 50, 100, 150, 200],
      LEVEL_9: [0, 25, 50, 75, 100],
      LEVEL_10: [0, 10, 20, 30, 40]
    };

    // 网格级别配置
    const GRID_LEVELS = {
      LEVEL_1: { 
        lon: 6, 
        lat: 4,
        bounds: {
          west: 72,
          east: 138,
          south: 4,
          north: 56
        }
      },
      LEVEL_2: { 
        lon: 30/60,
        lat: 30/60,
        bounds: {
          west: 115,
          east: 118,
          south: 38,
          north: 40
        }
      },
      LEVEL_3: { 
        lon: 15/60,
        lat: 10/60,
        bounds: {
          west: 116,
          east: 117,
          south: 39,
          north: 40
        }
      },
      LEVEL_4: {
        lon: 4/60, // 4'
        lat: 4/60,
        bounds: {
          west: 116,
          east: 116.5,
          south: 39,
          north: 39.5
        }
      },
      LEVEL_5: {
        lon: 2/60, // 2'
        lat: 2/60,
        bounds: {
          west: 116,
          east: 116.25,
          south: 39,
          north: 39.25
        }
      },
      LEVEL_6: {
        lon: 1/60, // 1'
        lat: 1/60,
        bounds: {
          west: 116,
          east: 116.1,
          south: 39,
          north: 39.1
        }
      },
      LEVEL_7: {
        lon: 1/240, // 1/4'
        lat: 1/240,
        bounds: {
          west: 116,
          east: 116.05,
          south: 39,
          north: 39.05
        }
      },
      LEVEL_8: {
        lon: 1/1920, // 1/32'
        lat: 1/1920,
        bounds: {
          west: 116,
          east: 116.01,
          south: 39,
          north: 39.01
        }
      },
      LEVEL_9: {
        lon: 1/3840, // 1/64'
        lat: 1/3840,
        bounds: {
          west: 116,
          east: 116.005,
          south: 39,
          north: 39.005
        }
      },
      LEVEL_10: {
        lon: 1/7680, // 1/128'
        lat: 1/7680,
        bounds: {
          west: 116,
          east: 116.002,
          south: 39,
          north: 39.002
        }
      }
    };

    // 中国区域边界
    const CHINA_BOUNDS = {
      west: 72.0,
      east: 138.0,
      south: 16.0,
      north: 56.0
    };

    // 网格编码配置
    const GRID_ENCODING = {
      LEVEL_1: {
        format: (lon, lat) => {
          // 确定南北半球
          const hemisphere = lat >= 0 ? 'N' : 'S';
          
          // 计算网格编号（根据图2的方向）
          // 对于北半球，从赤道向北，从西向东编号
          // 对于南半球，从赤道向南，从西向东编号
          const latIndex = Math.floor(Math.abs(lat) / 4);
          const lonIndex = Math.floor((lon - 72) / 6);
          const gridNumber = latIndex * 11 + lonIndex + 1; // 11是每行的网格数

          return `${hemisphere}${gridNumber}`;
        }
      },
      LEVEL_2: {
        format: (lon, lat, parentCode) => {
          // 提取父级编码的数字部分
          const parentNumber = parseInt(parentCode.substring(1));
          
          // 在父级网格内计算相对位置
          const baseLon = 72 + (Math.floor((parentNumber - 1) % 11)) * 6;
          const baseLat = Math.floor((parentNumber - 1) / 11) * 4;
          
          // 计算在父级网格内的位置
          const lonIndex = Math.floor((lon - baseLon) / (30/60));
          
          // 转换为A-V的字母
          const letter = String.fromCharCode(65 + lonIndex);
          
          return `${letter}`;
        }
      },
      LEVEL_3: {
        format: (lon, lat, parentCode, parentLetter) => {
          // 在父级网格内计算0-9的数字
          const baseLon = lon; // 使用完整经度
          const baseLat = lat; // 使用完整纬度
          
          // 计算在父级网格内的相对位置
          const index = Math.floor((lon % (30/60)) / (15/60)) * 3 +
                       Math.floor((lat % (30/60)) / (10/60));
          
          return `${index}`;
        }
      },
      LEVEL_4: {
        format: (lon, lat, parentCode) => {
          const index = Math.floor((lon % (15/60)) / (4/60)) * 3 +
                       Math.floor((lat % (10/60)) / (4/60));
          return `${index}`;
        }
      },
      LEVEL_5: {
        format: (lon, lat, parentCode) => {
          const index = Math.floor((lon % (4/60)) / (2/60)) * 2 +
                       Math.floor((lat % (4/60)) / (2/60));
          return `${index}`;
        }
      },
      LEVEL_6: {
        format: (lon, lat, parentCode) => {
          const index = Math.floor((lon % (2/60)) / (1/60)) * 2 +
                       Math.floor((lat % (2/60)) / (1/60));
          return `${index}`;
        }
      },
      LEVEL_7: {
        format: (lon, lat, parentCode) => {
          const index = Math.floor((lon % (1/60)) / (1/240)) * 4 +
                       Math.floor((lat % (1/60)) / (1/240));
          return `${index}`;
        }
      },
      LEVEL_8: {
        format: (lon, lat, parentCode) => {
          const index = Math.floor((lon % (1/240)) / (1/1920)) * 8 +
                       Math.floor((lat % (1/240)) / (1/1920));
          return `${index}`;
        }
      },
      LEVEL_9: {
        format: (lon, lat, parentCode) => {
          const index = Math.floor((lon % (1/1920)) / (1/3840)) * 2 +
                       Math.floor((lat % (1/1920)) / (1/3840));
          return `${index}`;
        }
      },
      LEVEL_10: {
        format: (lon, lat, parentCode) => {
          const index = Math.floor((lon % (1/3840)) / (1/7680)) * 2 +
                       Math.floor((lat % (1/3840)) / (1/7680));
          return `${index}`;
        }
      }
    };

    // 修改控件选项
    const levelOptions = [
      { value: 1, label: '一级(6°×4°)' },
      { value: 2, label: '二级(30\'×30\')' },
      { value: 3, label: '三级(15\'×10\')' },
      { value: 4, label: '四级(4\'×4\')' },
      { value: 5, label: '五级(2\'×2\')' },
      { value: 6, label: '六级(1\'×1\')' },
      { value: 7, label: '七级(1/4\'×1/4\')' },
      { value: 8, label: '八级(1/32\'×1/32\')' },
      { value: 9, label: '九级(1/64\'×1/64\')' },
      { value: 10, label: '十级(1/128\'×1/128\')' }
    ];

    // 修改createGridEntity函数中的性能优化逻辑
    const createGridEntity = (lon, lat, level) => {
      const gridLevel = GRID_LEVELS[`LEVEL_${level}`];
      const heightLevels = HEIGHT_LEVELS[`LEVEL_${level}`];
      
      // 检查是否在指定范围内
      const bounds = gridLevel.bounds;
      if (lon < bounds.west || lon >= bounds.east || 
          lat < bounds.south || lat >= bounds.north) {
        return;
      }

      const entities = [];

      // 获取完整的网格编码
      const getFullGridCode = (lon, lat, level) => {
        let code = '';
        for (let i = 1; i <= level; i++) {
          if (i === 1) {
            code = GRID_ENCODING[`LEVEL_${i}`].format(lon, lat);
          } else {
            code += GRID_ENCODING[`LEVEL_${i}`].format(lon, lat, code);
          }
        }
        return code;
      };

      // 根据级别调整显示参数
      const getDisplayParams = (level) => {
        const params = {
          gridAlpha: 0.1,          // 网格透明度
          outlineWidth: 2,         // 轮廓线宽度
          labelSize: 16,           // 标签大小
          labelScale: 1.0,         // 标签缩放
          labelBackground: true,    // 是否显示标签背景
          minDistance: 1.0e2,      // 最小可见距离
          maxDistance: 2.0e7       // 最大可见距离
        };

        if (level >= 7) {
          params.gridAlpha = 0.15;
          params.outlineWidth = 1;
          params.labelSize = Math.max(16 - (level - 6) * 2, 8);
          params.labelScale = 0.8;
          params.minDistance = 1.0e2;
          params.maxDistance = 5.0e5;
        }

        if (level >= 9) {
          params.gridAlpha = 0.2;
          params.outlineWidth = 0.5;
          params.labelSize = 8;
          params.labelScale = 0.6;
          params.minDistance = 1.0e2;
          params.maxDistance = 2.0e4;
        }

        return params;
      };

      const displayParams = getDisplayParams(level);

      // 创建每个高度层的网格
      heightLevels.forEach((height, index) => {
        // 为每个高度层创建水平网格面
        const horizontalGrid = viewer.value.entities.add({
          rectangle: {
            coordinates: Cesium.Rectangle.fromDegrees(
              lon,
              lat,
              lon + gridLevel.lon,
              lat + gridLevel.lat
            ),
            material: new Cesium.Color(1.0, 1.0, 0.0, displayParams.gridAlpha),
            outline: true,
            outlineColor: Cesium.Color.YELLOW,
            outlineWidth: displayParams.outlineWidth,
            height: height,
            distanceDisplayCondition: new Cesium.DistanceDisplayCondition(
              displayParams.minDistance,
              displayParams.maxDistance
            )
          }
        });
        entities.push(horizontalGrid);

        // 在每个高度层都添加编码标签
        if (showGridCode.value) {
          const centerLon = lon + gridLevel.lon / 2;
          const centerLat = lat + gridLevel.lat / 2;
          
          // 获取完整的网格编码，并添加高度层信息
          let gridCode = getFullGridCode(centerLon, centerLat, level);
          gridCode = `${gridCode}-${index + 1}`;

          // 如果不是第一层，则在上一层的高度和当前层的高度之间显示标签
          const labelHeight = index === 0 ? height : (height + heightLevels[index - 1]) / 2;

          const label = viewer.value.entities.add({
            position: Cesium.Cartesian3.fromDegrees(centerLon, centerLat, labelHeight),
            label: {
              text: gridCode,
              font: `${displayParams.labelSize}px Microsoft YaHei`,
              fillColor: Cesium.Color.WHITE,
              outlineColor: Cesium.Color.BLACK,
              outlineWidth: displayParams.outlineWidth,
              style: Cesium.LabelStyle.FILL_AND_OUTLINE,
              verticalOrigin: Cesium.VerticalOrigin.CENTER,
              horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
              pixelOffset: new Cesium.Cartesian2(0, 0),
              showBackground: displayParams.labelBackground,
              backgroundColor: new Cesium.Color(0, 0, 0, 0.5),
              backgroundPadding: new Cesium.Cartesian2(7, 5),
              scale: displayParams.labelScale,
              scaleByDistance: new Cesium.NearFarScalar(
                displayParams.minDistance,
                1.2,
                displayParams.maxDistance,
                0.0
              ),
              distanceDisplayCondition: new Cesium.DistanceDisplayCondition(
                displayParams.minDistance,
                displayParams.maxDistance
              ),
              disableDepthTestDistance: Number.POSITIVE_INFINITY
            }
          });
          entities.push(label);
        }

        // 创建垂直连接线
        if (index < heightLevels.length - 1) {
          const corners = [
            [lon, lat],
            [lon + gridLevel.lon, lat],
            [lon + gridLevel.lon, lat + gridLevel.lat],
            [lon, lat + gridLevel.lat]
          ];

          corners.forEach(([cornerLon, cornerLat]) => {
            const verticalLine = viewer.value.entities.add({
              polyline: {
                positions: Cesium.Cartesian3.fromDegreesArrayHeights([
                  cornerLon, cornerLat, height,
                  cornerLon, cornerLat, heightLevels[index + 1]
                ]),
                width: displayParams.outlineWidth,
                material: new Cesium.Color(1.0, 1.0, 0.0, 0.8),
                distanceDisplayCondition: new Cesium.DistanceDisplayCondition(
                  displayParams.minDistance,
                  displayParams.maxDistance
                )
              }
            });
            entities.push(verticalLine);
          });
        }
      });

      gridEntities.value.set(`${level}_${lon}_${lat}`, entities);
    };

    // 初始化Cesium viewer
    const initViewer = () => {
      viewer.value = new Cesium.Viewer("cesiumContainer", {
        baseLayerPicker: true,
        timeline: false,
        animation: false,
        homeButton: false,
        navigationHelpButton: false,
        fullscreenButton: true,
        scene3DOnly: true,
        requestRenderMode: true,
        imageryProvider: new Cesium.ArcGisMapServerImageryProvider({
          url: "https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer"
        })
      });

      // 设置相机限制
      viewer.value.scene.screenSpaceCameraController.minimumZoomDistance = 100;
      viewer.value.scene.screenSpaceCameraController.maximumZoomDistance = 5000000;
      
      // 禁用地形深度测试以确保标签始终可见
      viewer.value.scene.globe.depthTestAgainstTerrain = false;

      // 性能优化设置
      viewer.value.scene.globe.enableLighting = true;

      // 设置背景色
      viewer.value.scene.backgroundColor = Cesium.Color.BLACK;
      viewer.value.scene.globe.baseColor = Cesium.Color.BLACK;
      viewer.value.scene.fog.enabled = false;

      // 设置初始视角
      const centerLon = 105; // 中国中心经度
      const centerLat = 35;  // 中国中心纬度
      const initialHeight = 5000000; // 初始高度5000km

      viewer.value.scene.camera.setView({
        destination: Cesium.Cartesian3.fromDegrees(centerLon, centerLat, initialHeight),
        orientation: {
          heading: 0.0,
          pitch: Cesium.Math.toRadians(-45),
          roll: 0.0
        }
      });

      // 等待相机设置完成后再更新网格
      setTimeout(() => {
        updateGrids();
      }, 100);
    };

    // 添加城市标记
    const addCityMarkers = () => {
      MAJOR_CITIES.forEach(city => {
        viewer.value.entities.add({
          position: Cesium.Cartesian3.fromDegrees(city.lon, city.lat),
          billboard: {
            image: createCityPin(),
            verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
            scale: 0.5
          },
          label: {
            text: city.name,
            font: '14px Microsoft YaHei',
            fillColor: Cesium.Color.WHITE,
            outlineColor: Cesium.Color.BLACK,
            outlineWidth: 2,
            style: Cesium.LabelStyle.FILL_AND_OUTLINE,
            verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
            horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
            pixelOffset: new Cesium.Cartesian2(0, -10)
          }
        });
      });
    };

    // 创建城市图标
    const createCityPin = () => {
      const canvas = document.createElement('canvas');
      canvas.width = 32;
      canvas.height = 32;
      const context = canvas.getContext('2d');

      context.beginPath();
      context.arc(16, 16, 8, 0, 2 * Math.PI, false);
      context.fillStyle = 'red';
      context.fill();
      context.lineWidth = 2;
      context.strokeStyle = 'white';
      context.stroke();

      return canvas;
    };

    // 更新网格显示
    const updateGrids = () => {
      // 清除现有网格
      gridEntities.value.forEach(entities => {
        entities.forEach(entity => {
          viewer.value.entities.remove(entity);
        });
      });
      gridEntities.value.clear();

      const gridLevel = GRID_LEVELS[`LEVEL_${currentLevel.value}`];
      const bounds = gridLevel.bounds;

      // 计算网格范围
      const startLon = Math.floor(bounds.west / gridLevel.lon) * gridLevel.lon;
      const endLon = Math.ceil(bounds.east / gridLevel.lon) * gridLevel.lon;
      const startLat = Math.floor(bounds.south / gridLevel.lat) * gridLevel.lat;
      const endLat = Math.ceil(bounds.north / gridLevel.lat) * gridLevel.lat;

      // 创建网格
      for (let lon = startLon; lon < endLon; lon += gridLevel.lon) {
        for (let lat = startLat; lat < endLat; lat += gridLevel.lat) {
          createGridEntity(lon, lat, currentLevel.value);
        }
      }

      // 安全地移动相机到目标区域
      try {
        const centerLon = (bounds.west + bounds.east) / 2;
        const centerLat = (bounds.south + bounds.north) / 2;
        const distance = calculateViewDistance(currentLevel.value, bounds);

        // 使用setView而不是flyTo
        viewer.value.scene.camera.setView({
          destination: Cesium.Cartesian3.fromDegrees(centerLon, centerLat, distance),
          orientation: {
            heading: 0.0,
            pitch: Cesium.Math.toRadians(-45),
            roll: 0.0
          }
        });
      } catch (error) {
        console.error('Camera movement error:', error);
      }
    };

    // 修改计算视角距离的函数
    const calculateViewDistance = (level, bounds) => {
      // 根据级别设置固定的观察距离
      const baseDistance = {
        1: 2000000,
        2: 500000,
        3: 200000,
        4: 100000,
        5: 50000,
        6: 20000,
        7: 10000,
        8: 5000,
        9: 1000,
        10: 500
      }[level] || 5000000; // 如果级别未定义，使用默认值

      return baseDistance;
    };

    // 监听选项变化
    watch([currentLevel, showGridCode], () => {
      updateGrids();
    });

    watch(showCities, (newValue) => {
      if (newValue) {
        addCityMarkers();
      } else {
        // 移除城市标记
        viewer.value.entities.values
          .filter(entity => MAJOR_CITIES.some(city => 
            entity.position && 
            Cesium.Cartesian3.equals(
              entity.position.getValue(Cesium.JulianDate.now()),
              Cesium.Cartesian3.fromDegrees(city.lon, city.lat)
            )
          ))
          .forEach(entity => viewer.value.entities.remove(entity));
      }
    });

    onMounted(() => {
      initViewer();
      updateGrids();
      if (showCities.value) {
        addCityMarkers();
      }
    });

    return {
      currentLevel,
      levelOptions,
      showGridCode,
      showCities
    };
  }
};
</script>

<style scoped>
.beidou-grid-map {
  width: 100%;
  height: 100%;
  position: relative;
}

#cesiumContainer {
  width: 100%;
  height: 100%;
}

.controls {
  position: absolute;
  top: 10px;
  left: 10px;
  background: rgba(0, 0, 0, 0.7);
  padding: 10px;
  border-radius: 4px;
  color: white;
  z-index: 1000;
}

.control-item {
  margin: 5px 0;
  display: flex;
  align-items: center;
  gap: 10px;
}

select {
  padding: 4px;
  border-radius: 4px;
}

input[type="checkbox"] {
  width: 16px;
  height: 16px;
}
</style> 